package com.bsj.sipgateway.sip.transmit;

import com.bsj.power.common.config.rocketmq.producer.BaseMqPushUtil;
import com.bsj.power.common.mapper.*;
import com.bsj.sipgateway.config.SipConfig;
import com.bsj.sipgateway.mq.producer.CommandUpProducer;
import com.bsj.sipgateway.sip.auth.RegisterLogicHandler;
import com.bsj.sipgateway.sip.event.EventPublisher;
import com.bsj.sipgateway.sip.session.VideoStreamSessionManager;
import com.bsj.sipgateway.sip.transmit.callback.DeferredResultHolder;
import com.bsj.sipgateway.sip.transmit.cmd.impl.SIPCommander;
import com.bsj.sipgateway.sip.transmit.request.ISIPRequestProcessor;
import com.bsj.sipgateway.sip.transmit.request.impl.*;
import com.bsj.sipgateway.sip.transmit.response.ISIPResponseProcessor;
import com.bsj.sipgateway.sip.transmit.response.impl.*;
import com.bsj.sipgateway.util.MediaPortUtils;
import com.bsj.sipgateway.util.SpringBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import redis.clients.bsj.JedisClusterBSJ;

import javax.sip.RequestEvent;
import javax.sip.ResponseEvent;
import javax.sip.SipProvider;
import javax.sip.header.CSeqHeader;
import javax.sip.message.Request;
import javax.sip.message.Response;
import java.util.concurrent.Executor;

/**
 * @author bsj-chenjunkang
 * @Description: SIP信令处理分配
 * @date 2022/8/24
 */
@Component
public class SIPProcessorFactory {

    @Value("${annexFile.path}")
    private String annexPath;


    @Autowired
    private SipConfig sipConfig;

    @Autowired
    private RegisterLogicHandler handler;

    @Autowired
    private EventPublisher publisher;

    @Autowired
    private SIPCommander cmder;

    @Autowired
    private DeferredResultHolder deferredResultHolder;


    @Autowired
    private InviteResponseProcessor inviteResponseProcessor;

    @Autowired
    private ByeResponseProcessor byeResponseProcessor;

    @Autowired
    private CancelResponseProcessor cancelResponseProcessor;

    @Autowired
    private OtherResponseProcessor otherResponseProcessor;

    @Autowired
    private MessageResponseProcessor messageResponseProcessor;

    @Autowired
    private SubscribeResponseProcessor subscribeResponseProcessor;

    @Autowired
    private CommandUpProducer commandUpProducer;

    @Autowired
    private VideoStreamSessionManager streamSessionManager;

    @Autowired
    private MediaPortUtils mediaPortUtils;

    @Autowired
    private JedisClusterBSJ jedisClusterBSJ;

    @Autowired
    private VideoOpLogMapper videoOpLogMapper;

    @Autowired
    private FaultLogMapper faultLogMapper;

    @Autowired
    @Qualifier("powerVideoAsync")
    private Executor taskExecutor;

    @Autowired
    private AlarmReportMapper alarmReportMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private BaseMqPushUtil baseMqPushUtil;

    @Autowired
    private FaultMapper faultMapper;

    @Autowired
    private CmdLogMapper cmdLogMapper;

    @Value("${sip.cvrIds}")
    private String cvrIds;
    @Value("${sip.needAlarmIn}")
    private Boolean needAlarmIn;

    @Autowired
    private DeviceChannelMapper deviceChannelMapper;


    // 注：这里使用注解会导致循环依赖注入，暂用springBean
    private SipProvider tcpSipProvider;

    // 注：这里使用注解会导致循环依赖注入，暂用springBean
    private SipProvider udpSipProvider;

    public ISIPRequestProcessor createRequestProcessor(RequestEvent evt) {
        Request request = evt.getRequest();
        String method = request.getMethod();
        if (Request.INVITE.equals(method)) {
            InviteRequestProcessor processor = new InviteRequestProcessor();
            processor.setRequestEvent(evt);
            processor.setTcpSipProvider(getTcpSipProvider());
            processor.setUdpSipProvider(getUdpSipProvider());
            processor.setSipConfig(sipConfig);
            processor.setMediaPortUtils(mediaPortUtils);
            return processor;
        } else if (Request.REGISTER.equals(method)) {
            RegisterRequestProcessor processor = new RegisterRequestProcessor();
            processor.setRequestEvent(evt);
            processor.setTcpSipProvider(getTcpSipProvider());
            processor.setUdpSipProvider(getUdpSipProvider());
            processor.setHandler(handler);
            processor.setPublisher(publisher);
            processor.setSipConfig(sipConfig);
            processor.setDeviceMapper(deviceMapper);
            processor.setJedisClusterBSJ(jedisClusterBSJ);
            processor.setVideoOpLogMapper(videoOpLogMapper);
            processor.setFaultLogMapper(faultLogMapper);
            return processor;
        } else if (Request.SUBSCRIBE.equals(method)) {
            SubscribeRequestProcessor processor = new SubscribeRequestProcessor();
            return processor;
        } else if (Request.ACK.equals(method)) {
            AckRequestProcessor processor = new AckRequestProcessor();
            processor.setRequestEvent(evt);
            processor.setUdpSipProvider(udpSipProvider);
            processor.setCommandUpProducer(commandUpProducer);
            processor.setSessionManager(streamSessionManager);
            return processor;
        } else if (Request.BYE.equals(method)) {
            ByeRequestProcessor processor = new ByeRequestProcessor();
            processor.setRequestEvent(evt);
            return processor;
        } else if (Request.CANCEL.equals(method)) {
            CancelRequestProcessor processor = new CancelRequestProcessor();
            processor.setRequestEvent(evt);
            return processor;
        } else if (Request.MESSAGE.equals(method)) {
            MessageRequestProcessor processor = new MessageRequestProcessor();
            processor.setRequestEvent(evt);
            processor.setTcpSipProvider(getTcpSipProvider());
            processor.setUdpSipProvider(getUdpSipProvider());
            processor.setDeferredResultHolder(deferredResultHolder);
            processor.setPublisher(publisher);
            processor.setCmder(cmder);
            processor.setCommandUpProducer(commandUpProducer);
            processor.setSipConfig(sipConfig);
            processor.setJedisClusterBSJ(jedisClusterBSJ);
            processor.setTaskExecutor(taskExecutor);
            processor.setAlarmReportMapper(alarmReportMapper);
            processor.setDeviceMapper(deviceMapper);
            processor.setBaseMqPushUtil(baseMqPushUtil);
            processor.setFaultMapper(faultMapper);
            processor.setAnnexPath(annexPath);
            processor.setCvrIds(cvrIds);
            processor.setNeedAlarmIn(needAlarmIn);
            processor.setDeviceChannelMapper(deviceChannelMapper);
            processor.setCmdLogMapper(cmdLogMapper);
            return processor;
        } else if (Request.NOTIFY.equalsIgnoreCase(method)) {
            NotifyRequestProcessor processor = new NotifyRequestProcessor();
            processor.setRequestEvent(evt);
            processor.setTcpSipProvider(getTcpSipProvider());
            processor.setUdpSipProvider(getUdpSipProvider());
            processor.setPublisher(publisher);
            return processor;
        } else {
            OtherRequestProcessor processor = new OtherRequestProcessor();
            return processor;
        }
    }

    public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) {
        Response response = evt.getResponse();
        CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
        String method = cseqHeader.getMethod();
        if (Request.INVITE.equals(method)) {
            return inviteResponseProcessor;
        } else if (Request.BYE.equals(method)) {
            return byeResponseProcessor;
        } else if (Request.CANCEL.equals(method)) {
            return cancelResponseProcessor;
        } else if (Request.MESSAGE.equals(method)) {
            return messageResponseProcessor;
        } else if (Request.SUBSCRIBE.equals(method)) {
            return subscribeResponseProcessor;
        } else {
            return otherResponseProcessor;
        }
    }

    private SipProvider getTcpSipProvider() {
        if (tcpSipProvider == null) {
            tcpSipProvider = (SipProvider) SpringBeanFactory.getBean("tcpSipProvider");
        }
        return tcpSipProvider;
    }

    private SipProvider getUdpSipProvider() {
        if (udpSipProvider == null) {
            udpSipProvider = (SipProvider) SpringBeanFactory.getBean("udpSipProvider");
        }
        return udpSipProvider;
    }

}
